#include <Bsp/bsp_can1.h>


#define DBG_TAG "can2"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>


#define CAN_DEV_NAME                "can2"              // CAN 设备名称
#define CAN_FILTER_START_INDEX      0                   // CAN 硬件滤波器 CAN1 0-13 CAN2 14-28

static struct rt_semaphore          rx_sem;             // 用于接收消息的信号量
static struct rt_can_msg            rx_msg = {0};       // 接收消息
static rt_device_t                  can_dev;            // CAN 设备句柄


// 接收数据回调函数
static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size)
{
    if(size > 0)
    {
        // hdr 值为 - 1，表示直接从 uselist 链表读取数据
        rx_msg.hdr = -1;
        // 从 CAN 读取一帧数据
        rt_device_read(can_dev, 0, &rx_msg, sizeof(struct rt_can_msg));
        // CAN 接收到数据后产生中断，调用此回调函数，然后发送接收信号量
        rt_sem_release(&rx_sem);
    }
    return RT_EOK;
}


bool bsp_can2_tx_transmit(struct rt_can_msg* msg)
{
    rt_size_t  size;
    // 发送一帧 CAN 数据
    size = rt_device_write(can_dev, 0, msg, sizeof(struct rt_can_msg));

    LOG_D("ID:%x TXDAT: %02x %02x %02x %02x %02x %02x %02x %02x", msg->id,
            msg->data[0], msg->data[1], msg->data[2], msg->data[3],
            msg->data[4] ,msg->data[5], msg->data[6], msg->data[7]);
    if (size == 0)
    {
        return false;
    }
    return true;
}

bool bsp_can2_rx_transmit(struct rt_can_msg* rxmsg, int32_t wait)
{
    // 阻塞等待接收信号量
    if(rt_sem_take(&rx_sem, wait) != RT_EOK)
        return false;

    memcpy(rxmsg, &rx_msg, sizeof(struct rt_can_msg));

    // 打印数据 ID 及内容
    LOG_D("ID:%x RXDAT: %02x %02x %02x %02x %02x %02x %02x %02x", rxmsg->id,
            rxmsg->data[0], rxmsg->data[1], rxmsg->data[2], rxmsg->data[3],
            rxmsg->data[4] ,rxmsg->data[5], rxmsg->data[6], rxmsg->data[7]);

    return true;
}

int bsp_can2_init(void)
{
    rt_err_t res;

    // 查找 CAN 设备
    can_dev = rt_device_find(CAN_DEV_NAME);
    if (!can_dev)
    {
        LOG_E("find %s failed!\n", CAN_DEV_NAME);
    }

    // 初始化 CAN 接收信号量
    rt_sem_init(&rx_sem, "can_rx", 0, RT_IPC_FLAG_FIFO);

    // 以中断接收及发送方式打开 CAN 设备
    res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
    RT_ASSERT(res == RT_EOK);

    // 设置 CAN 为正常通讯模式
    res = rt_device_control(can_dev, RT_CAN_CMD_SET_MODE, (void *)RT_CAN_MODE_NORMAL);
    RT_ASSERT(res == RT_EOK);

    // 设置 CAN 通信的波特率为 1000kbit/s
    res = rt_device_control(can_dev, RT_CAN_CMD_SET_BAUD, (void *)CAN1MBaud);
    RT_ASSERT(res == RT_EOK);

    // 设置接收回调函数
    rt_device_set_rx_indicate(can_dev, can_rx_call);

    LOG_D("bsp_can2_init success");
    return RT_EOK;
}
// 导出到自动初始化
//INIT_DEVICE_EXPORT(bsp_can_init);

int bsp_can2_filter_init(uint8_t node_id)
{
    rt_err_t res;
#ifdef RT_CAN_USING_HDR
    struct rt_can_filter_item items[] =
    {
        //CAN 硬件滤波器 CAN1 0-13 CAN2 14-28
        //MASK = (~(0x00)) 标识完全匹配   MASK = (~(0x7f)) 表示ID = 0-7F 都可以接收
//        {(0x000),           RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 0 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //NMT      设置节点状态
//        {(0x080),           RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 1 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //SYNC
//        {(0x700 | node_id), RT_CAN_STDID, RT_CAN_RTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 2 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //NMT      远程帧获取节点状态
//
//        {(0x200 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 3 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //RxPDO0   客户端(主)下发服务器(从)接收
//        {(0x300 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 4 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //RxPDO1
//        {(0x400 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 5 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //RxPDO2
//        {(0x500 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 6 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //RxPDO3
//        {(0x600 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 7 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //RxSDO

//        {(0x180 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 8 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //TxPDO0   从站上传主站接收
//        {(0x280 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 9 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //TxPDO1
//        {(0x380 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 10 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //TxPDO2
//        {(0x480 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 11 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},   //TxPDO3
//        {(0x580 | node_id), RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x7f)), 12 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},  //TxSDO

          {(0x7FF),           RT_CAN_STDID, RT_CAN_DTR, CAN_FILTERMODE_IDMASK, (~(0x00)), 0 + CAN_FILTER_START_INDEX, RT_NULL, RT_NULL},    //自定义串口通道
    };
    struct rt_can_filter_config cfg = {sizeof(items) / sizeof(struct rt_can_filter_item), 1, items}; /* 一共有 5 个过滤表 */
    /* 设置硬件过滤表 */
    res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg);
    RT_ASSERT(res == RT_EOK);
#endif
    return RT_EOK;
}

#if 1
int can2_sample(int argc, char *argv[])
{
    struct rt_can_msg msg = {0};
    rt_err_t res = RT_EOK;
    rt_size_t  size;

    msg.id = 0x78;              /* ID 为 0x78 */
    msg.ide = RT_CAN_STDID;     /* 标准格式 */
    msg.rtr = RT_CAN_DTR;       /* 数据帧 */
    msg.len = 8;                /* 数据长度为 8 */
    // 待发送的 8 字节数据
    msg.data[0] = 0x00;
    msg.data[1] = 0x11;
    msg.data[2] = 0x22;
    msg.data[3] = 0x33;
    msg.data[4] = 0x44;
    msg.data[5] = 0x55;
    msg.data[6] = 0x66;
    msg.data[7] = 0x77;

    bsp_can2_tx_transmit(&msg);

    bsp_can2_rx_transmit(&msg, 5000);

    return res;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(can2_sample, can device sample);
#endif
